package com.sydsen.imager.processor;

import com.sydsen.imager.elements.Element;
import com.sydsen.imager.elements.Text;
import com.sydsen.imager.util.FontUtil;
import sun.font.FontDesignMetrics;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: syh
 * @Date: 2021/11/4
 * @Description:
 */
public class TextProcessor implements IProcessor<Text> {
    @Override
    public void process(Text text, List<Element> elements) {
        if (text.breakLine()) {
            List<Text> texts = getBreakLineElements(text);
            elements.addAll(texts);
        } else {
            elements.add(text);
        }
    }

    private boolean isChineseChar(char c) {
        return String.valueOf(c).matches("[\u4e00-\u9fa5]");
    }

    private List<String> computeLines(String text, Font font, int maxLineWidth) {

        List<String> computedLines = new ArrayList<>();     //最终要返回的多行文本（不超限定宽度）
        String strToComputer = "";
        String word = "";             //一个完整单词
        boolean hasWord = false;      //是否获得一个完整单词
        char[] chars = text.toCharArray();
        int count = 0;

        //遍历每个字符，拆解单词（一个中文算一个单词，其他字符直到碰到空格算一个单词）
        for (int i = 0; i < chars.length; i++) {
            if (count++ > 500) {
                break;      //防止意外情况进入死循环
            }
            char c = chars[i];          //当前字符
            if (isChineseChar(c) || c == ' ' || i == (chars.length - 1)) {
                word += c;             //如果是中文或空格或最后一个字符，一个中文算一个单词, 其他字符遇到空格认为单词结束
                hasWord = true;
            } else {
                word += c;             //英文或其他字符，加入word，待组成单词
            }

            //获得了一个完整单词，加入当前行，并计算限宽
            if (hasWord) {

                //计算现有文字宽度
                int originWidth = FontUtil.getTextWidth(strToComputer, font);

                //计算单个单词宽度（防止一个单词就超限宽的情况）
                int wordWidth = FontUtil.getTextWidth(word, font);

                //单词加入待计算字符串
                strToComputer += word;

                //加入了新单词之后的宽度
                int newWidth = originWidth + wordWidth;

                //一个单词就超限，要暴力换行
                if (wordWidth > maxLineWidth) {
                    //按比例计算要取几个字符（不是特别精准）
                    int fetch = (int) ((float) (maxLineWidth - originWidth) / (float) wordWidth * word.length());   //本行剩余宽度所占word宽度比例，乘以字符长度（字符不等宽的时候不太准）
                    strToComputer = strToComputer.substring(0, strToComputer.length() - word.length() + fetch);     //去除最后的word的后半截
                    computedLines.add(strToComputer);                      //加入计算结果列表
                    strToComputer = "";
                    i -= (word.length() - fetch);                          //遍历计数器回退word.length()-fetch个
                }
                //行宽度超出限宽，则去除最后word，加入计算结果列表
                else if (newWidth > maxLineWidth) {
                    strToComputer = strToComputer.substring(0, strToComputer.length() - word.length());      //去除最后word
                    computedLines.add(strToComputer);                       //加入计算结果列表
                    strToComputer = "";
                    i -= word.length();                                     //遍历计数器回退word.length()个
                }

                word = "";
                hasWord = false;        //重置标记
            }
        }

        if (strToComputer != "") {
            computedLines.add(strToComputer);                               //加入计算结果列表
        }

        return computedLines;
    }

    public List<Text> getBreakLineElements(Text element) {
        List<Text> texts = new ArrayList<>();
        List<String> lines = computeLines(element.text(), element.font(), element.width());
        int y = element.y();
        for (int i = 0; i < lines.size(); i++) {
            if (i < element.lines()) {
                String txt = lines.get(i);
                //如果计该行是要取的最后一行，但不是整体最后一行，则加...
                if (i == element.lines() - 1 && i < lines.size() - 1) {
                    if (!"".equals(element.append())) {
                        txt = txt.substring(0, txt.length() - 1) + element.append();
                    }
                }
                Text text = new Text(txt, element.font(), element.x(), y);
                text.color(element.color());
                text.strikeThrough(element.strikeThrough());
                text.center(element.center());
                text.middle(element.middle());
                text.lineNumber(i + 1);
                text.alpha(element.alpha());
                text.rotate(element.rotate());
                texts.add(text);

                //累加高度
                y += element.height();
            } else {
                break;
            }
        }
        return texts;
    }
}
